package drawing

import (
	"fmt"
	"gonum.org/v1/plot"
	"gonum.org/v1/plot/plotter"
	"gonum.org/v1/plot/vg"
	"image/color"
	"math"
	"regexp"
	"robot/study/LiveRobot/define"
	"robot/study/LiveRobot/reptile"
	"strconv"
	"strings"
	"time"
)

//DrawEquationAnswer 绘制函数回复
func (draw *Drawing) DrawEquationAnswer() {
	var answer string
	answer = "目前支持：绘制曲线(一个固定的直线，无入参)"
	rsp := &define.Msg{
		Msg_type: "private",
		Number:   int(draw.Msg.UserId),
		Msg:      answer,
	}
	reptile.Sendmsg(rsp)
}

//DrawCurve 绘制曲线
func (draw *Drawing) DrawCurve() {
	fileLocation := define.DrawingFileLocation + "functions.png"
	s := ""
	//y=kx^2+bx+c
	re := regexp.MustCompile(`[+-]?[\d.]*x\^[+-]?[\d.]*|[+-]?[\d.]*x|[+-]?[\d.]`)
	match := re.FindAllString(draw.Msg.RawMessage, -1)

	for _, v := range match {
		s += v
	}

	fmt.Println(match)
	p := plot.New()

	p.Title.Text = "Functions"
	p.X.Label.Text = "X"
	p.Y.Label.Text = "Y"
	// 绘制x^2
	quad := plotter.NewFunction(func(x float64) float64 {
		var y float64
		for _, v := range match {
			index := strings.Index(v, "^")
			if index == -1 {
				if strings.Contains(v, "x") {
					newv := v[:len(v)-1]
					k, _ := strconv.ParseFloat(newv, 64)
					y = y + k*x
				} else {
					k, _ := strconv.ParseFloat(v, 64)
					y = y + k
				}

			} else {
				newv := v[:index-1]
				k, _ := strconv.ParseFloat(newv, 64)
				if k == 0 {
					if newv == "-" {
						k = -1
					} else {
						k = 1
					}
				}
				newv2 := v[index+1:]
				k2, _ := strconv.ParseFloat(newv2, 64)
				y = y + k*math.Pow(x, k2)
			}
		}
		return y
	})
	quad.Color = color.RGBA{R: 255, B: 0, A: 255}

	// An exponential function 2^x
	//exp := plotter.NewFunction(func(x float64) float64 { return math.Pow(2, x) })
	//exp.Dashes = []vg.Length{vg.Points(2), vg.Points(2)}
	//exp.Width = vg.Points(2)
	//exp.Color = color.RGBA{G: 255, A: 255}
	// Add the functions and their legend entries.
	p.Add(quad)
	p.Legend.Add(s, quad)
	p.Legend.ThumbnailWidth = 0.5 * vg.Inch

	// Set the axis ranges.  Unlike other data sets,
	// functions don't set the axis ranges automatically
	// since functions don't necessarily have a
	// finite range of x and y values.
	p.X.Min = -10
	p.X.Max = 10
	p.Y.Min = -10
	p.Y.Max = 10
	if err := p.Save(4*vg.Inch, 4*vg.Inch, fileLocation); err != nil {
		panic(err)
	}

	time.Sleep(time.Second * 5)
	rspImage := &define.Msg{
		Msg_type: "group",
		Number:   define.QUN,
		Msg:      "[CQ:image,file=file:///" + fileLocation + "]",
	}
	reptile.Sendmsg(rspImage)
}

//DrawLinearFunction 绘制一次函数
func (draw *Drawing) DrawLinearFunction() {
	fileLocation := define.DrawingFileLocation + "functions.png"
	fmt.Println(draw.Msg.RawMessage)
	idx1 := strings.Index(draw.Msg.RawMessage, "=")
	idx2 := strings.Index(draw.Msg.RawMessage, "x")

	if idx1 == -1 || idx2 == -1 {
		rspImage := &define.Msg{
			Msg_type: "group",
			Number:   define.QUN,
			Msg:      "一次函数格式不正确",
		}
		reptile.Sendmsg(rspImage)
		return
	}
	k := 1.0
	b := 0.0
	kn, _ := strconv.ParseFloat(draw.Msg.RawMessage[idx1+1:idx2], 64)
	bn, _ := strconv.ParseFloat(draw.Msg.RawMessage[idx2+1:], 64)
	if kn == 0 {

	} else {
		k = kn
	}
	if bn == 0 {

	} else {
		b = bn
	}

	p := plot.New()

	p.Title.Text = "Functions"
	p.X.Label.Text = "X"
	p.Y.Label.Text = "Y"

	//绘制y=kx
	quad := plotter.NewFunction(func(x float64) float64 { return k*x + b })
	quad.Color = color.RGBA{B: 255, A: 255}

	p.Add(quad)
	if b == 0 {
		p.Legend.Add("y="+strconv.Itoa(int(k))+"x", quad)
	} else {
		p.Legend.Add("y="+strconv.Itoa(int(k))+"x"+strconv.Itoa(int(b)), quad)
	}
	p.Legend.ThumbnailWidth = 0.5 * vg.Inch

	p.X.Min = -10
	p.X.Max = 10
	p.Y.Min = -10
	p.Y.Max = 10
	if err := p.Save(5*vg.Inch, 4*vg.Inch, fileLocation); err != nil {
		panic(err)
	}

	time.Sleep(time.Second * 1)
	rspImage := &define.Msg{
		Msg_type: "group",
		Number:   define.QUN,
		Msg:      "[CQ:image,file=file:///" + fileLocation + "]",
	}
	reptile.Sendmsg(rspImage)
}

//DrawSanJiaoFunc 绘制三角函数
func DrawSanJiaoFunc() {

}
